// src/main/utils/fileManager.js

const { dialog, shell } = require('electron')
const path = require('path')
const fs = require('fs').promises

/**
 * 文件管理工具类
 * 封装文件操作、权限检查、多平台兼容等功能
 */
class FileManager {
  constructor() {
    this.supportedImageExtensions = ['jpg', 'jpeg', 'png', 'gif', 'bmp', 'webp']
    this.platform = process.platform
  }

  /**
   * 检查文件是否存在
   * @param {string} filePath - 文件路径
   * @returns {Promise<boolean>}
   */
  async fileExists(filePath) {
    try {
      await fs.access(filePath)
      return true
    } catch {
      return false
    }
  }

  /**
   * 检查目录是否存在
   * @param {string} dirPath - 目录路径
   * @returns {Promise<boolean>}
   */
  async directoryExists(dirPath) {
    try {
      const stat = await fs.stat(dirPath)
      return stat.isDirectory()
    } catch {
      return false
    }
  }

  /**
   * 获取文件信息
   * @param {string} filePath - 文件路径
   * @returns {Promise<Object>}
   */
  async getFileInfo(filePath) {
    try {
      const stat = await fs.stat(filePath)
      const ext = path.extname(filePath).toLowerCase().slice(1)
      return {
        name: path.basename(filePath),
        path: filePath,
        size: stat.size,
        extension: ext,
        isImage: this.supportedImageExtensions.includes(ext),
        modifiedTime: stat.mtime,
        createdTime: stat.birthtime
      }
    } catch (error) {
      console.error('[FileManager] 获取文件信息失败:', error)
      return null
    }
  }

  /**
   * 打开图片选择对话框
   * @param {Object} options - 选项
   * @returns {Promise<string[]>} 选择的文件路径数组
   */
  async openImageDialog(options = {}) {
    console.log('[FileManager] 打开图片选择对话框，平台:', this.platform)
    
    const defaultOptions = {
      title: '选择要导入的图片',
      multiSelections: true,
      allowFolders: this.platform === 'darwin', // macOS 支持选择文件夹
      filters: [
        { name: 'Images', extensions: this.supportedImageExtensions },
        { name: 'All Files', extensions: ['*'] }
      ]
    }

    const dialogOptions = {
      ...defaultOptions,
      ...options,
      properties: [
        'openFile',
        ...(defaultOptions.multiSelections ? ['multiSelections'] : []),
        ...(defaultOptions.allowFolders ? ['openDirectory'] : [])
      ]
    }

    try {
      const { canceled, filePaths } = await dialog.showOpenDialog(dialogOptions)
      
      if (!canceled && filePaths.length > 0) {
        console.log('[FileManager] 用户选择文件:', filePaths)
        
        // 验证文件
        const validFiles = []
        for (const filePath of filePaths) {
          const fileInfo = await this.getFileInfo(filePath)
          if (fileInfo && fileInfo.isImage) {
            validFiles.push(fileInfo)
          } else if (fileInfo && await this.directoryExists(filePath)) {
            // 如果是目录，扫描其中的图片文件
            const imagesInDir = await this.scanDirectoryForImages(filePath)
            validFiles.push(...imagesInDir)
          }
        }
        
        console.log('[FileManager] 有效图片文件:', validFiles.map(f => f.path))
        return validFiles.map(f => f.path)
      } else {
        console.log('[FileManager] 用户取消了选择')
        return []
      }
    } catch (error) {
      console.error('[FileManager] 打开图片对话框失败:', error)
      return []
    }
  }

  /**
   * 打开目录选择对话框
   * @param {Object} options - 选项
   * @returns {Promise<string|null>} 选择的目录路径
   */
  async openDirectoryDialog(options = {}) {
    console.log('[FileManager] 打开目录选择对话框，平台:', this.platform)
    
    const defaultOptions = {
      title: '选择目录',
      properties: ['openDirectory']
    }

    const dialogOptions = {
      ...defaultOptions,
      ...options
    }

    try {
      const { canceled, filePaths } = await dialog.showOpenDialog(dialogOptions)
      
      if (!canceled && filePaths.length > 0) {
        const selectedPath = filePaths[0]
        console.log('[FileManager] 用户选择目录:', selectedPath)
        
        // 验证目录权限
        if (await this.directoryExists(selectedPath)) {
          return selectedPath
        } else {
          console.error('[FileManager] 选择的路径不是有效目录:', selectedPath)
          return null
        }
      } else {
        console.log('[FileManager] 用户取消了目录选择')
        return null
      }
    } catch (error) {
      console.error('[FileManager] 打开目录对话框失败:', error)
      return null
    }
  }

  /**
   * 扫描目录中的图片文件
   * @param {string} dirPath - 目录路径
   * @returns {Promise<Array>} 图片文件信息数组
   */
  async scanDirectoryForImages(dirPath) {
    console.log('[FileManager] 扫描目录中的图片:', dirPath)
    
    try {
      const files = await fs.readdir(dirPath)
      const imageFiles = []
      
      for (const file of files) {
        const filePath = path.join(dirPath, file)
        const fileInfo = await this.getFileInfo(filePath)
        
        if (fileInfo && fileInfo.isImage) {
          imageFiles.push(fileInfo)
        }
      }
      
      console.log('[FileManager] 找到图片文件数量:', imageFiles.length)
      return imageFiles
    } catch (error) {
      console.error('[FileManager] 扫描目录失败:', error)
      return []
    }
  }

  /**
   * 保存标注数据到文件
   * @param {string} filePath - 保存路径
   * @param {Object} data - 标注数据
   * @returns {Promise<boolean>}
   */
  async saveAnnotationData(filePath, data) {
    console.log('[FileManager] 保存标注数据:', filePath)
    
    try {
      const dir = path.dirname(filePath)
      await fs.mkdir(dir, { recursive: true })
      
      const jsonData = JSON.stringify(data, null, 2)
      await fs.writeFile(filePath, jsonData, 'utf8')
      
      console.log('[FileManager] 标注数据保存成功')
      return true
    } catch (error) {
      console.error('[FileManager] 保存标注数据失败:', error)
      return false
    }
  }

  /**
   * 导出标注数据
   * @param {Object} annotationData - 标注数据
   * @returns {Promise<string|null>} 保存的文件路径
   */
  async exportAnnotationData(annotationData) {
    console.log('[FileManager] 导出标注数据')
    
    try {
      const { canceled, filePath } = await dialog.showSaveDialog({
        title: '导出标注数据',
        defaultPath: `annotations_${Date.now()}.json`,
        filters: [
          { name: 'JSON Files', extensions: ['json'] },
          { name: 'All Files', extensions: ['*'] }
        ]
      })
      
      if (!canceled && filePath) {
        const success = await this.saveAnnotationData(filePath, annotationData)
        if (success) {
          console.log('[FileManager] 标注数据导出成功:', filePath)
          return filePath
        }
      } else {
        console.log('[FileManager] 用户取消了导出')
      }
      
      return null
    } catch (error) {
      console.error('[FileManager] 导出标注数据失败:', error)
      return null
    }
  }

  /**
   * 在文件管理器中显示文件
   * @param {string} filePath - 文件路径
   */
  async showInFileManager(filePath) {
    try {
      await shell.showItemInFolder(filePath)
      console.log('[FileManager] 在文件管理器中显示:', filePath)
    } catch (error) {
      console.error('[FileManager] 显示文件失败:', error)
    }
  }

  /**
   * 获取平台特定的文件路径分隔符
   * @returns {string}
   */
  getPathSeparator() {
    return path.sep
  }

  /**
   * 检查文件权限
   * @param {string} filePath - 文件路径
   * @returns {Promise<boolean>}
   */
  async checkFilePermission(filePath) {
    try {
      await fs.access(filePath, fs.constants.R_OK)
      return true
    } catch {
      return false
    }
  }
}

module.exports = FileManager 